package com.mall.product.server;

import com.mall.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@SpringBootTest
public class test {

    @Autowired
    private RedisService redisService;

    @Test
    public void test_lua () {
        Integer skuId=1; //模拟用户在前台选择购买的sku
        StringBuilder sb = new StringBuilder();
        sb.append("if (redis.call('exists', KEYS[1]) == 1) then");    // 判断key是否存在
        sb.append("    local stock = tonumber(redis.call('get', KEYS[1]));");   // 获取锁
        sb.append("    if (stock == -1) then");
        sb.append("        return 1;");
        sb.append("    end;");
        sb.append("    if (stock > 0) then");
        sb.append("        redis.call('decrby', KEYS[1], 1);");    // 商品数量减1
        sb.append("        return stock;");
        sb.append("    end;");
        sb.append("    return 0;");
        sb.append("end;");
        sb.append("return -1;");
        String STOCK_LUA = sb.toString();

        DefaultRedisScript<Long> objectDefaultRedisScript = new DefaultRedisScript<>();
        objectDefaultRedisScript.setScriptText(STOCK_LUA);
        objectDefaultRedisScript.setResultType(Long.class);

        ArrayList<String> keys = new ArrayList<>();     // 脚本中的KEYS参数
        keys.add("TEST_LUA:"+skuId);

        ExecutorService service = Executors.newFixedThreadPool(20);
        for (int i = 0; i < 2; i++) {
            int finalI = i;
            service.execute(new Runnable() {
                @Override
                public void run() {
                    int execute = Integer.parseInt(redisService.redisTemplate.execute(objectDefaultRedisScript, keys).toString());
                    if (execute != 0) {
                        log.info("线程" + finalI + "抢到了商品!!!");
                    } else {
                        log.info("线程" + finalI + "未抢到商品");
                    }
                }
            });
        }
    }
}
